<?php
namespace app\im\controller;
use think\App;
use app\ApiRest;
use app\BaseController;
use app\im\model\ImUser;
use app\im\model\ImChat;
use app\im\model\ImMessage;
use think\Exception;

class MessageHandler
{
    protected $connect_name = 'longbing_im_connect_';
    protected $chat_name    = 'longbing_chat_';
    protected $uniacid_wss = 'wss';


//    public function __construct ()
//    {
//        
//    }
    //登陆
    public function login($server ,$client_id ,$data) 
    {
        //获取参数
        $value = [];
        if(isset($data['data'])) $value = $data['data'];
        if(empty($value)) return ;
        $user_id = null;
        $uniacid = '7777';
        if(isset($value['user_id'])) $user_id = $value['user_id'];
        if(isset($value['uniacid'])) $uniacid = $value['uniacid'];
        if(empty($user_id) || empty($uniacid)) return ; 
        //获取用户信息
        $user = $this->getUser($user_id ,$uniacid);
        //判断用户是否存在
        if(empty($user)) {
            return $server->push($client_id ,json_encode(['action' => 'login' ,'status' => false ,'message'=> lang('login error') ,'data' =>[]]));
        }
        //设置用户连接数据
        $user['client_id'] = $client_id;
        $cache_user = $this->setCacheUser($user_id ,$user ,$uniacid);
        //设置用户连接
        $cache_connect = $this->setConnect($client_id ,['user_id' => $user_id ,'uniacid' => $uniacid]);
        //判断缓存是否插入成功
        if(empty($cache_user) || empty($cache_connect)) $server->push($client_id ,json_encode(lang('login error')));
        //返回登陆成功
        $server->push($client_id ,json_encode(['action' => 'login' ,'status' => true ,'message'=> 'login success.' ,'data' =>$user]));
    }
    
    //检查登录
    public function checkLogin($client_id ,$data = [])
    {
        $result = false;
        //获取连接信息
        $connect = $this->getConnect($client_id);
        //如果没有登录
        if(empty($connect) || !isset($connect['user_id']) || !isset($connect['uniacid']))
        {
            $user_id = null;
            $uniacid = '7777';
            //判断用户id是否存在
            if(!isset($data['user_id'])) return $result;
            //获取用户id
            $user_id = $data['user_id'];
            
            //获取uniacid
            if(isset($data['uniacid'])) $uniacid = $data['uniacid'];
            //获取用户数据
            $user = $this->getUser($user_id ,$uniacid);
            //判断用书是否存在
            
            if(empty($user)) return $result;
            //设置用户连接数据
            $user['client_id'] = $client_id;
            $cache_user = $this->setCacheUser($user_id ,$user ,$uniacid);
            //设置用户连接
            $cache_connect = $this->setConnect($client_id ,['user_id' => $user_id ,'uniacid' => $uniacid]);
            
            //判断缓存是否插入成功
            if(!empty($cache_user) && !empty($cache_connect)) $result = true;
        }else{
            $result = true;
        }
        return $result;
    }

    //退出
    public function logout($client_id)
    {
        $this->delConnect($client_id);
    }
    //发送消息
    public function sendMessage($server ,$client_id ,$data)
    {
        //登录检查
        if(!$this->checkLogin($client_id ,$data['data'])){
            $server->push($client_id ,json_encode(['action' => 'login' ,'status' => false ,'message'=> 'login error ,please check login param.' ,'data' =>[]]));
            return;    
        }
        //获取用户是否登录
        $connect = $this->getConnect($client_id);
        $user = null;
        if(empty($connect) || !isset($connect['user_id']) || !isset($connect['uniacid'])) 
        {
            return;
        }else{
            $user = $this->getUser($connect['user_id'] ,$connect['uniacid']);
        }
        
        //判断用户是否存在
        if(empty($user)) return ;
        //判断连接是否正确
        if(!isset($user['client_id']) || !in_array($user['client_id'], [$client_id]))
        {
            $user['client_id'] = $client_id;
            $this->setCacheUser($connect['user_id'], $user ,'ws');
        }
        //检查消息
        $value['message_type']    = 'text';
        $value['status']  = 1;
        $value['user_id'] = $connect['user_id'];
        $value['uniacid'] = $connect['uniacid'];
        $value['create_time'] = time();
        if(isset($data['data'])){
            $data = $data['data'];
        }else{
            return;
        }
        //判断接受者是否存在
        if(isset($data['target_id'])) {
            $value['target_id'] = $data['target_id'];
        }else{
            return ;
        }
        //判断数据类型是否存在
        if(isset($data['type']))   $value['message_type'] = $data['type'];
        //判断状态是否存在
        if(isset($data['status'])) $value['status'] = $data['status'];
        //判断发送者是否存在
        if(isset($data['user_id'])) $value['user_id'] = $data['user_id'];
        //判断uniacid是否存在
        if(isset($data['uniacid'])) $value['uniacid'] =  $data['uniacid'];
        if(isset($data['chat_id'])) 
        {
            $value['chat_id'] =  $data['chat_id'];
        }else{
//            $data = $this->getChat($value['user_id'], $value['target_id'] ,$data['uniacid']);
            $value['chat_id'] = $this->getChatId($value['user_id'], $value['target_id'] ,$data['uniacid'] ,true);
            //$server->push($client_id , json_encode($value ,true));die;
        }
        //判断发送消息是否存在
        if(isset($data['content'])) {
            $value['content'] = $data['content'];
        }else{
            return ;
        }
        
        //检查数据（防止伪造数据的存在）
        $target = $this->getUser($value['target_id'] ,$value['uniacid']);
        //判断用户是否存在
        if(empty($target)) return;
        //存储数据
//      $push_data = array(
//          'action' => 'addMessage',
//          'event' => 'asyncAddMessage',
//          'message' => $value
//      );
//        $i = 1000000;
//        while($i>0)
//        {
//            publisher(json_encode($push_data ,true));
//            $i = $i -1;
//        }
//      publisher(json_encode($push_data ,true));
        $resultAddMsg = false ;


        //随机模拟发送消息失败情况
        /*mt_srand();
        $demoError = mt_rand(0, 1);

        if($demoError){
            if(isset($value['chat_id']) && !empty($value['chat_id'])) $resultAddMsg = asyncAddMessage($value);
        }*/

        if(isset($value['chat_id']) && !empty($value['chat_id'])) $resultAddMsg = asyncAddMessage($value);

        //By.jingshuixian  如果消息存储失败,直接返回
        if(!$resultAddMsg){
            $server->push($client_id ,json_encode(['action' => 'sendMessage' ,'status' => $resultAddMsg,'data' => $value] ,true));
            return  false ;
        }

        //判断用户是否登录
        if(isset($target['client_id'])) {
            $value['time']   = date('Y-m-d H:i:s', time());
            try{
                $server->push($target['client_id'] , json_encode(['action' => 'getNewMessage' ,'status' => $resultAddMsg , 'data' => $value] ,true));
            }catch (Exception $e){
                //echo "$server->push error" ;
            }

            //向消息接受者发送未读消息数量
            //$this->getCustomerUnReadMessageCount($server ,$target['client_id'] ,['target_id' => $data['user_id']]);
            $this->getCustomer($server ,$target['client_id'] ,['data' => ['user_id' => $value['target_id'] ,'target_id' => $value['user_id'] ,'uniacid' => $value['uniacid']]]);
            $this->getCustomerUnReadMessageCount($server ,$target['client_id'] ,['data' => ['user_id' => $value['target_id'] ,'target_id' => $value['user_id'] ,'uniacid' => $value['uniacid']]]);
            $this->getUnReadMessageCount($server ,$target['client_id'] ,['data' => ['user_id' => $value['target_id'] ,'target_id' => $value['user_id'] ,'uniacid' => $value['uniacid']]]);
        }else{
            //发送服务通知
//          $push_data = array(
//              'action'  => 'sendMessageWxServiceNotice',
//              'event'   => 'longbingSendMessageWxServiceNotice',
//              'message' => $value
//          );
//          publisher(json_encode($push_data ,true));
            longbingSendMessageWxServiceNotice($value);
            
        }    
        $value['status'] = 1;
        $value['creat_time'] = time();
        $value['time']   = date('Y-m-d H:i:s', time());
        $server->push($client_id ,json_encode(['action' => 'sendMessage' ,'status' => $resultAddMsg,'data' => $value] ,true));
        //存储数据
//        $push_data = array(
//            'action' => 'addMessage',
//            'event' => 'asyncAddMessage',
//            'message' => $value
//        );
//        publisher(json_encode($push_data ,true) ,1000);
        //发送用户总的未读数据获取用户
        
    }
    //获取用户缓存
    function getCacheUser($user_id ,$uniacid = '7777')
    {
        $key = 'longbing_ws_card_user_' . $user_id;
        if(!hasCache($key ,$uniacid)) return null;
        return getCache($key ,$uniacid);
    }
    
    //设置用户缓存数据
    function setCacheUser($user_id ,$value ,$uniacid = '7777')
    {
        $key = 'longbing_ws_card_user_' . $user_id;
        return setCache ( $key, $value, 3600, $uniacid);
    }
    
    //获取用户信息
    function getUser($user_id ,$uniacid ='7777')
    {
        //判断缓存是否存在    
        $user = $this->getCacheUser($user_id ,$uniacid);
        if(!empty($user)) return $user;
//      //生成查询类
//      $user_model = new ImUser();
//      //获取数据
//      $user = $user_model->getUser(['id' => $user_id ,'uniacid' => $uniacid]);
        $user = longbingGetUser($user_id ,$uniacid);
        if(empty($user)) return null;
        $this->setCacheUser($user_id ,$user ,$uniacid);
        return $user;
    }
    //获取当前连接状态
    function getConnect($client_id ,$uniacid = 'ws')
    {
        $key = $this->connect_name . $client_id;
        $connect = getCache($key ,$uniacid);
        return $connect;
    }
    //设置连接状态
    function setConnect($client_id ,$value , $uniacid = 'ws')
    {
        $key = $this->connect_name . $client_id;
        return setCache ( $key, $value, 3600, $uniacid);
    }
    //注销连接
    function delConnect($client_id ,$uniacid = 'ws')
    {
        $key = $this->connect_name . $client_id;
        $connect = $this->getConnect($client_id ,$uniacid);
        if(empty($connect) || !isset($connect['user_id']) || !isset($connect['uniacid'])) return false;
        $user = $this->getUser($connect['user_id'] ,$connect['uniacid']);
        if(isset($user['client_id'])){
            unset($user['client_id']);
            $this->setCacheUser($connect['user_id'],$user, $connect['uniacid']);
        }
        delCache($key ,$uniacid);
    }
    //获取所有chat
    function getChats($user_id ,$uniacid = '7777' ,$is_update = false)
    {
//        $key = $this->chat_name . $user_id;
//        $chats = [];
//        //判断是否更新
//        if($is_update)
//        {
//            $chat_model = new ImChat();
//            $chats_data = $chat_model->listChatAll($user_id ,$uniacid);
//            foreach($chats_data as $chat)
//            {
//                if(!isset($chat['chat_id']) || !isset($chat['user_id']) || !isset($chat['target_id'])) continue;
//                $customer_id = $chat['user_id'];
//                if(!in_array($chat['user_id'], [$user_id])) $customer_id = $chat['target_id'];
//                $chats[$customer_id] = $chat['chat_id'];
//            }
//            if(!empty($chats)) $this->setChat($user_id ,$chats ,$uniacid);
//        }else{
//            if(hasCache($key ,$uniacid)){
//                $chats = getCache($key ,$uniacid);
//            }else{
//                $chats = $this->getChats($user_id ,$uniacid ,true);
//            }
//        }
//        return $chats;
        $key = $this->chat_name . $user_id;
        $chats = [];
        if(hasCache($key ,$uniacid)){
             $chats = getCache($key ,$uniacid);
        } 
        return $chats;
    }
    //获取用户与客户的chat
    function getChatId($user_id ,$customer_id ,$uniacid ,$is_create = false)
    {
//        //获取chats
//        $chats = $this->getChats($user_id ,$uniacid);
//        $chat_id = null;
//        //判断数据是否存在
//        if(!isset($chats[$customer_id])){
//            $this->createChat(['user_id' => $user_id ,'target_id' => $customer_id ,'uniacid' => $uniacid ,'create_time' => time()]);
//            $chat_id = $this->getChatId($user_id ,$customer_id ,$uniacid);
//        }else{
//            $chat_id = $this->getChats($user_id ,$uniacid)[$customer_id];
//        }
//        //返回数据
//        return $chat_id;
        //获取chats
        $chats = $this->getChats($user_id ,$uniacid);
        $chat_id = null;
        //判断数据是否存在
        if(!isset($chats[$customer_id])){
            //从数据库中查询数据
            $chat = $this->getChat($user_id, $customer_id ,$uniacid);
            if(empty($chat))
            {
                if(!empty($is_create)){
                    $chat_id = $this->createChat(['user_id' => $user_id ,'target_id' => $customer_id ,'uniacid' => $uniacid ,'create_time' => time()]);
//                  $chat_id = $this->getChatId($user_id ,$customer_id ,$uniacid);
                }
            }else{
                $chats[$customer_id] = $chat['chat_id'];
                $this->setChat($user_id, $chats ,$uniacid);
            }
            
        }else{
            $chat_id = $this->getChats($user_id ,$uniacid)[$customer_id];
        }
        //返回数据
        return $chat_id;
    }
    
    //获取chat
    function getChat($user_id ,$customer_id ,$uniacid = '7777')
    {
        $chat_model = new ImChat();
        $chat = $chat_model->getChat($user_id ,$customer_id ,$uniacid);
        return $chat;
    }
    
    //设置Chat
    function setChat($user_id ,$value ,$uniacid ='7777')
    {
        $key = $this->chat_name . $user_id;
        return setCache($key, $value, 60, $uniacid);
    }
    
    //创建Chat
    function createChat($data)
    {
        $chat_model = new ImChat();
        $result = $chat_model->createChat($data);
        //$this->getChats($data['user_id'] ,$data['uniacid'] ,true);
        return $result;
    }
    
    //获取客户列表
    function listCustomer($data)
    {
        //获取参数列表
        $param = $this->$data;
        //获取用户列表
        $user_id = $param['user_id'];
        //判断用户是否存在
        if(empty($user_id)) return $this->error('not login ,please login again.');
        //生成分页信息
        $page_config = array(
            'page' => 1,
            'page_count' => 10
        );
        //获取分页信息
        if(isset($param['page']) && $param['page'] > 0) $page_config['page'] = $param['page'];
        if(isset($param['page_count']) && $param['page_count'] > 0) $page_config['page_count'] = $param['page_count'];
        //生成查询模型
        $chat_model = new ImChat();
        //生成消息查询模型
        $message_model = new ImMessage();
        //生成用户查询模型
//      $user_model = new ImUser();
        //生成查询
        $page_config['total'] = $chat_model->listChatCount($user_id);
        $chats = $chat_model->listChat($user_id ,$page_config);
        if(!empty($chats))
        {
            foreach($chats as $key => $value)
            {
                $lastmessage = $message_model->lastMessage(['chat_id' => $value['id']]);
                $value['lastmessage'] = $lastmessage;
                $customer_id = null;
                if(!in_array($value['user_id'], [$user_id])) $customer_id = $value['user_id'];
                if(!in_array($value['target_id'], [$user_id])) $customer_id = $value['target_id'];
//              $value['customer'] = $user_model->getUser(['id' => $customer_id]);
                $value['customer'] = longbingGetUser($customer_id ,$value['uniacid']);
                $chats[$key] = $value;
            }
        }
        $page_config['total_page'] = (int)($page_config['total'] / $page_config['page_count']);
        if(($page_config['total'] % $page_config['page_count']) > 0) $page_config['total_page'] = $page_config['total_page'] + 1;
        $result = $page_config;
        $result['chats'] = $chats;
        return $this->success($result);
    }

    //获取未读消息总数
    public function getUnReadMessageCount($server ,$client_id ,$data)
    {
        //登录检查
        if(!$this->checkLogin($client_id ,$data['data'])){
            $server->push($client_id ,json_encode(['action' => 'login' ,'status' => false ,'message'=> 'login error ,please check login param.' ,'data' =>[]]));
            return;    
        }
        //获取用户是否登录
        $connect = $this->getConnect($client_id);
        $user = null;
        if(empty($connect) || !isset($connect['user_id']) || !isset($connect['uniacid'])) 
        {
            return;
        }else{
            $user = $this->getUser($connect['user_id'] ,$connect['uniacid']);
        }
        //判断用户是否存在
        if(empty($user)) return ;
        //判断连接是否正确
        if(!isset($user['client_id']) || !in_array($user['client_id'], [$client_id]))
        {
            $user['client_id'] = $client_id;
            $this->setCacheUser($connect['user_id'], $user ,'ws');
        }
        //获取未读消息总数
        $message_model = new ImMessage();
//        $server->push($client_id ,json_encode($user));
        $count = $message_model->listMessageCount(['target_id' => $user['id'] ,'status' => 1]);
//        $count = $message_model->listMessageCount(['status' => 1]); 
        $server->push($client_id ,json_encode(['action' => 'getUnReadMessageCount' ,'status' => true ,'message'=> '' ,'data' =>['count' => $count]]));
        return;
    }
    //获取用户未读消息数
    public function getCustomerUnReadMessageCount($server ,$client_id ,$data)
    {
        //登录检查
        if(!$this->checkLogin($client_id ,$data['data'])){
            $server->push($client_id ,json_encode(['action' => 'login' ,'status' => false ,'message'=> 'login error ,please check login param.' ,'data' =>[]]));
            return;    
        }
        if(!isset($data['data']['target_id'])) return; 
        $customer_id = $data['data']['target_id'];
        //获取用户是否登录
        $connect = $this->getConnect($client_id);
        $user = null;
        if(empty($connect) || !isset($connect['user_id']) || !isset($connect['uniacid'])) 
        {
            return;
        }else{
            $user = $this->getUser($connect['user_id'] ,$connect['uniacid']);
        }
        //判断用户是否存在
        if(empty($user)) return ;
        //判断连接是否正确
        if(!isset($user['client_id']) || !in_array($user['client_id'], [$client_id]))
        {
            $user['client_id'] = $client_id;
            $this->setCacheUser($connect['user_id'], $user ,'ws');
        }
        //获取未读消息总数
        $message_model = new ImMessage();
        $chat_id = $this->getChatId($user['id'] ,$customer_id ,$user['uniacid'] ,true);
        if(empty($chat_id)) return;
        $count = $message_model->listMessageCount(['user_id' => $customer_id,'target_id' => $user['id'] ,'status' => 1]);
//        $count = $message_model->listMessageCount(['status' => 1]); 
        $server->push($client_id ,json_encode(['action' => 'getCustomerUnReadMessageCount' ,'status' => true ,'message'=> '' ,'data' =>['count' => $count ,'target_id' => $customer_id ,'user_id' => $user['id']]]));
        return;
    }
    //获取客户信息
    public function getCustomer($server ,$client_id ,$data)
    {
        //登录检查
        if(!$this->checkLogin($client_id ,$data['data'])){
            $server->push($client_id ,json_encode(['action' => 'login' ,'status' => false ,'message'=> 'login error ,please check login param.' ,'data' =>[]]));
            return;    
        }
        if(!isset($data['data'])) return;
        if(!isset($data['data']['user_id'])) return;
        if(!isset($data['data']['target_id'])) return;
        if(!isset($data['data']['uniacid'])) return;
        $user_id = $data['data']['user_id'];
        $customer_id = $data['data']['target_id'];
        $uniacid = $data['data']['uniacid'];
        //生成关系操作类
        $chat_model = new ImChat();
        //获取chat_id 
        $chat_id = $this->getChatId($user_id ,$customer_id ,$uniacid ,true);
        if(empty($chat_id)) return;
        //获取数据
        $chat = $chat_model->getChatById($chat_id);
        if(empty($chat)) return;
        //获取客户信息
        $customer = $this->getUser($customer_id ,$uniacid);
        $chat['customer'] = $customer;
        $chat['time'] = date('Y-m-d H:i:s', time());
        if(isset($chat['update'])) $chat['time'] = date('Y-m-d H:i:s', $chat['update']);
        
        $message_model = new ImMessage();
        //获取最后一条消息
        $last_message = $message_model->lastMessage(['chat_id' => $chat_id]);
        $chat['lastmessage'] = $last_message;
        //获取未读客户数据数量
        $not_rear_message_count = $message_model->listMessageCount(['chat_id' => $chat_id ,'user_id' => $customer_id ,'target_id' =>$user_id  ,'status' => 1]);
        $chat['not_read_message_count'] = $not_rear_message_count;
        //返回数据
        $server->push($client_id ,json_encode(['action' => 'getCustomer' ,'status' => true ,'data' => $chat ,'message' => ''] ,true));
    }

    //检查链接是否正常
    public function checkWs($server ,$client_id ,$data)
    {
        if(!isset($data['data']['check']) || !in_array($data['data']['check'], ['78346+SJDHFA.longbing'])) return ;
//        $server->push($client_id ,json_encode(['action' => 'checkWs' ,'status' => true ,'message'=> '' ,'data' =>['check' => '78346+SJDHFA.longbing']]));  
        $server->push($client_id ,json_encode(['action' => 'checkWs' ,'status' => true ,'message' => '' ,'data' => ['check' => '78346+SJDHFA.longbing']]));
     }
    //标记消息已读
    public function readMessage($server ,$client_id ,$data)
    {
        //登录检查
        if(!$this->checkLogin($client_id ,$data['data'])){
            $server->push($client_id ,json_encode(['action' => 'login' ,'status' => false ,'message'=> 'login error ,please check login param.' ,'data' =>[]]));
            return;    
        }
        //获取用户是否登录
        $connect = $this->getConnect($client_id);
        $user = null;
        if(empty($connect) || !isset($connect['user_id']) || !isset($connect['uniacid'])) 
        {
            return;
        }else{
            $user = $this->getUser($connect['user_id'] ,$connect['uniacid']);
        }
        //判断用户是否存在
        if(empty($user)) return ;
        //判断连接是否正确
        if(!isset($user['client_id']) || !in_array($user['client_id'], [$client_id]))
        {
            $user['client_id'] = $client_id;
            $this->setCacheUser($connect['user_id'], $user ,'ws');
        }
        
	
        if(!isset($data['data']['target_id'])) return ;
        $target_id = $data['data']['target_id'];
        if(isset($data['data']['uniacid'])) $uniacid = $data['data']['uniacid'];
        if(isset($user['uniacid'])) $uniacid   = $user['uniacid'];
        $user_id   = $user['id'];
        $chat_id   = $this->getChatId($user_id, $target_id ,$uniacid , true);
        if(empty($chat_id)) return;
        //设置已读数据
        $message_model = new ImMessage();
        $message_model->readMessage(['chat_id' => $chat_id ,'user_id' => $target_id ,'target_id' => $user_id ,'deleted' => 0]);
        //发数据给自己
        $this->getCustomer($server ,$client_id ,['data' => ['user_id' => $user_id ,'target_id' => $target_id,'uniacid' => $uniacid]]);
            //
        $this->getUnReadMessageCount($server ,$client_id ,['data' => ['user_id' => $user_id,'target_id' => $target_id ,'uniacid' => $uniacid]]);
        
    }
    
}
